package com.movisol.messengercommunicator.helper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.movisol.messengercommunicator.data.CommunicatorRoot;
import com.movisol.messengercommunicator.data.CommunicatorUri;
import com.movisol.messengercommunicator.data.Contact;
import com.movisol.messengercommunicator.data.Conversation;
import com.movisol.messengercommunicator.data.Message;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;

public class MessengerCommunicatorHelper {
	
	private final static String COMMUNICATOR_URI_CLASS = "CommunicatorUri";
	private final static String COMMUNICATOR_ROOT_CLASS = "CommunicatorRoot";
	private final static String CONTACT_CLASS = "Contact";
	private final static String CONVERSATION_CLASS = "Conversation";
	private final static String MESSAGE_CLASS = "Message";
	private final static String CONTACT_ID_ATTR = "ContactId";
	private final static String CONVERSATION_ID_ATTR = "ConversationId";
	private final static String MESSAGE_PUBLIC_ID_ATTR = "MessagePublicId";
	private final static String DATE_CREATED_ATTR = "DateCreated";
	
	
	//Restrict the instantiation of the class
	private MessengerCommunicatorHelper()
	{}
	
	public static Conversation findConversationById(CommunicatorRoot conversationsList, String conversationId) {
		
		if(conversationsList != null)
			for(Conversation cnv : conversationsList.getConversations())
			{
				if(cnv.getConversationId().equals(conversationId))
					return cnv;
			}
		
		return null;
	}
	
	public static String generateSignatureForCommunicatorRoot(List<Message> messageList) {
		
		String signature = "";
		if(messageList != null)
			for(Message msg : messageList)
			{
				signature += msg.getBody();
				if(msg.getConversationId() != null && msg.getConversationId().length() > 0)
					signature += msg.getConversationId();
				else
					if(msg.getContacts() != null && msg.getContacts().size() > 0)
					{
						for(Contact contact : msg.getContacts())
						signature += contact.getContactId();//concatenateContactsIdAlphabetic(msg.getContacts());
					}
			}
		return signature;
	}
	
	private static String concatenateContactsIdAlphabetic(List<Contact> contacts)
	{
		List<String> contactsId = new ArrayList<String>();
		//Construct the necessary data for the signature
		for(Contact contact : contacts)
		{
			contactsId.add(contact.getContactId());
		}

		Collections.sort(contactsId);
		
		String tmp = null;
		if(contactsId.size() > 0)
		{
			tmp = "";
			for(String s : contactsId)
			{
				tmp += s.toLowerCase();
			}
		}
		
		return tmp;
	}

	public static String generateConversationId(List<Contact> contacts) {
		
		return concatenateContactsIdAlphabetic(contacts);
	}
	
	public static CommunicatorUri parseXMLConversationToObject(String xmlResource)
	{
		return parseXMLCommunicatorUriToObject(xmlResource);
	}
	

	public static CommunicatorUri parseXMLConversationMessagesToObject(String xmlResource)
	{
		return parseXMLCommunicatorUriToObject(xmlResource);
	}
	
	private static CommunicatorUri parseXMLCommunicatorUriToObject(String xmlResource)
	{
		XStream xstream = new XStream();
		CommunicatorUri communicatorUri = null;
		
		try {
			xstream.alias(COMMUNICATOR_URI_CLASS, CommunicatorUri.class);
			
			communicatorUri = (CommunicatorUri) xstream.fromXML(xmlResource);

		} catch (CannotResolveClassException e) {

			return null;
		} catch (XStreamException e) {
			return null;
		}
				
		return communicatorUri;
	}
	
	public static CommunicatorRoot parseXMLConversationListToObject(String xmlResource)
	{
		return parseXMLtoCommunicatorRoot(xmlResource);
	}
	

	public static CommunicatorRoot parseXMLConversationMessagesListToObject(String xmlResource)
	{
		return parseXMLtoCommunicatorRoot(xmlResource);
	}
	
	
	private static CommunicatorRoot parseXMLtoCommunicatorRoot(String xmlResource)
	{
		XStream xstream = new XStream();
		CommunicatorRoot communicatorRoot = null;
		
		try {
			xstream.alias(COMMUNICATOR_ROOT_CLASS, CommunicatorRoot.class);

			xstream.alias(CONTACT_CLASS, Contact.class);
			xstream.useAttributeFor(Contact.class, CONTACT_ID_ATTR);
			
			
			xstream.alias(CONVERSATION_CLASS, Conversation.class);
			xstream.useAttributeFor(Conversation.class, CONVERSATION_ID_ATTR);
			
			xstream.alias(MESSAGE_CLASS, Message.class);
			xstream.useAttributeFor(Message.class, MESSAGE_PUBLIC_ID_ATTR);
			xstream.useAttributeFor(Message.class, CONTACT_ID_ATTR);
			xstream.useAttributeFor(Message.class, DATE_CREATED_ATTR);
			
			communicatorRoot = (CommunicatorRoot) xstream.fromXML(xmlResource);

		} catch (CannotResolveClassException e) {
			return null;
		} catch (XStreamException e) {
			return null;
		}catch (Exception e) {
			return null;
		}

		
		return communicatorRoot;
	}
	
	public static String parseCommunicatorRootToXML(CommunicatorRoot cr)
	{
		
		XStream xstream = new XStream();
		String xml = null;
		
		try {
			xstream.alias(COMMUNICATOR_ROOT_CLASS, CommunicatorRoot.class);
			xstream.alias(MESSAGE_CLASS, Message.class);
			xstream.alias(CONTACT_CLASS, Contact.class);
			xml =  xstream.toXML(cr);

		} catch (CannotResolveClassException e) {
			return null;
		} catch (XStreamException e) {
			return null;
		}

		
		return xml;
	}

	public static Conversation findConversationByConversationId(String ci, List<Conversation> conversations) {
		
		Conversation conversation = new Conversation();
		conversation.setContacts(new ArrayList<Contact>());
//		conversation.getContacts().add(contactToChatWith);
		
		for(Conversation conver :conversations)
		{
			if(conver.getConversationId().equals(ci))
			{
				conversation.setConversationId(conver.getConversationId());
				conversation.setLastMessage(conver.getLastMessage());
				conversation.setUri(conver.getUri());
				
				for(Contact contact : conver.getContacts())
				{
					Contact contacto = new Contact();
					contacto.setContactId(contact.getContactId());
					contacto.setName(contact.getCalculatedName());
					contacto.setEmail(contact.getEmail());
					conversation.getContacts().add(contacto);
				}
				
				break;
			}
		}
		
		return conversation;
		
		
	}



}
